/**
 * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 */

package com.iwindplus.log.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.iwindplus.base.domain.constant.CommonConstant;
import com.iwindplus.base.domain.enums.BizCodeEnum;
import com.iwindplus.base.domain.exception.BizException;
import com.iwindplus.base.mongo.service.impl.MongoBaseServiceImpl;
import com.iwindplus.base.util.PatternUtil;
import com.iwindplus.log.domain.dto.MailLogDTO;
import com.iwindplus.log.domain.dto.MailLogSearchDTO;
import com.iwindplus.log.domain.vo.MailLogPageVO;
import com.iwindplus.log.domain.vo.MailLogVO;
import com.iwindplus.log.server.dal.model.MailLogDO;
import com.iwindplus.log.server.service.MailLogService;
import com.iwindplus.mgt.client.power.UserClient;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import net.dreamlu.mica.core.utils.StringUtil;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 邮箱日志业务层接口实现类.
 *
 * @author zengdegui
 * @since 2018/9/1
 */
@Service
@CacheConfig(cacheNames = {"mailLog"})
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class MailLogServiceImpl extends MongoBaseServiceImpl<MailLogDO>
    implements MailLogService {

    private final UserClient userClient;

    @Override
    public String save(MailLogDTO entity) {
        if (ObjectUtil.isEmpty(entity.getBizNumber())) {
            entity.setBizNumber(StringUtil.getUUID());
        }
        entity.setTos(HtmlUtil.unescape(entity.getTos()));
        if (CharSequenceUtil.isNotBlank(entity.getCcs())) {
            entity.setCcs(HtmlUtil.unescape(entity.getCcs()));
        }
        if (CharSequenceUtil.isNotBlank(entity.getBccs())) {
            entity.setCcs(HtmlUtil.unescape(entity.getCcs()));
        }
        if (Objects.isNull(entity.getSendCount())) {
            entity.setSendCount(1);
        }
        if (Objects.isNull(entity.getResult())) {
            entity.setResult(Boolean.FALSE);
        }
        final MailLogDO model = BeanUtil.copyProperties(entity, MailLogDO.class);
        super.save(model);
        entity.setId(model.getId());
        return entity.getId();
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean removeByIds(List<String> ids) {
        final Criteria criteria = Criteria.where(CommonConstant.DbConstant.ID).in(ids);
        final Query query = Query.query(criteria);
        List<MailLogDO> data = super.list(query);
        if (CollUtil.isEmpty(data)) {
            throw new BizException(BizCodeEnum.DATA_NOT_EXIST);
        }
        super.removeByIds(ids, false);
        return Boolean.TRUE;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean edit(MailLogDTO entity) {
        MailLogDO data = super.getById(entity.getId());
        if (Objects.isNull(data)) {
            throw new BizException(BizCodeEnum.DATA_NOT_EXIST);
        }
        if (CharSequenceUtil.isNotBlank(entity.getTos())) {
            entity.setTos(HtmlUtil.unescape(entity.getTos()));
        }
        if (CharSequenceUtil.isNotBlank(entity.getCcs())) {
            entity.setCcs(HtmlUtil.unescape(entity.getCcs()));
        }
        if (CharSequenceUtil.isNotBlank(entity.getBccs())) {
            entity.setCcs(HtmlUtil.unescape(entity.getCcs()));
        }
        if (Objects.isNull(entity.getVersion())) {
            entity.setVersion(data.getVersion());
        }
        final MailLogDO model = BeanUtil.copyProperties(entity, MailLogDO.class);
        super.updateById(model);
        return Boolean.TRUE;
    }

    @Override
    public IPage<MailLogPageVO> page(MailLogSearchDTO entity) {
        final PageDTO<MailLogDO> page = new PageDTO<>(entity.getCurrent(), entity.getSize());
        Criteria criteria = new Criteria();
        if (CharSequenceUtil.isNotBlank(entity.getBizNumber())) {
            criteria.and("bizNumber").is(entity.getBizNumber());
        }
        if (CharSequenceUtil.isNotBlank((entity.getSubject()))) {
            criteria.and("subject").regex(PatternUtil.getPatternLike(entity.getSubject()));
        }
        if (CharSequenceUtil.isNotBlank((entity.getContent()))) {
            criteria.and("content").regex(PatternUtil.getPatternLike(entity.getContent()));
        }
        if (CharSequenceUtil.isNotBlank((entity.getNickName()))) {
            criteria.and("nickName").is(entity.getNickName().trim());
        }
        if (CharSequenceUtil.isNotBlank((entity.getUsername()))) {
            criteria.and("username").is(entity.getUsername().trim());
        }
        if (CharSequenceUtil.isNotBlank((entity.getTos()))) {
            criteria.and("tos").regex(PatternUtil.getPatternLike(entity.getTos()));
        }
        if (Objects.nonNull(entity.getResult())) {
            criteria.and("result").is(entity.getResult());
        }
        if (CharSequenceUtil.isNotBlank(entity.getJobNumber())) {
            Long userId = GatewayLogServiceImpl.getUserIdByJobNumber(userClient, entity.getJobNumber());
            entity.setUserId(userId);
        } else if (CharSequenceUtil.isNotBlank(entity.getMobile())) {
            Long userId = GatewayLogServiceImpl.getUserIdByMobile(userClient, entity.getMobile());
            entity.setUserId(userId);
        }
        if (Objects.nonNull(entity.getUserId())) {
            criteria.and(CommonConstant.UserConstant.USER_ID).is(entity.getUserId());
        }
        Query query = new Query(criteria);
        List<OrderItem> orders = page.getOrders();
        if (CollUtil.isEmpty(orders)) {
            orders = new ArrayList<>(10);
            OrderItem orderItem = OrderItem.desc("modifiedTime");
            orders.add(orderItem);
            page.setOrders(orders);
        }
        final IPage<MailLogDO> modelPage = super.page(page, query);
        return modelPage.convert(model -> BeanUtil.copyProperties(model, MailLogPageVO.class));
    }

    @Cacheable(key = "#root.methodName + '_' + #p0", condition = "#p0 != null", unless = "#result == null")
    @Override
    public MailLogVO getDetail(String id) {
        MailLogDO data = super.getById(id);
        if (Objects.isNull(data)) {
            throw new BizException(BizCodeEnum.DATA_NOT_EXIST);
        }
        return BeanUtil.copyProperties(data, MailLogVO.class);
    }
}
